#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2021 Intel Corporation
#                    Borys Popławski <borysp@invisiblethingslab.com>

import click
import voluptuous

try:
    from tomllib import TOMLDecodeError
except ImportError:
    from tomli import TOMLDecodeError

from graminelibos import Manifest

def validate_define(_ctx, _param, values):
    ret = {}
    for value in values:
        try:
            k, v = value.split('=', 1)
        except ValueError:
            k, v = value, True
        ret[k] = v
    return ret

@click.command()
@click.option('--string', '-c')
@click.option('--define', '-D', multiple=True, callback=validate_define)
@click.option('--check/--no-check', default=True,
    help='check the manifest for correctness against builtin schema')
@click.argument('infile', type=click.File('r'), required=False)
@click.argument('outfile', type=click.File('wb'), default='-')
@click.option('--chroot',
    type=click.Path(exists=True, dir_okay=True, file_okay=False),
    help='Measure a chroot directory, not the host filesystem')
@click.pass_context
def main(ctx, string, define, infile, outfile, check, chroot):
    if not bool(string) ^ bool(infile):
        ctx.fail('specify exactly one of (infile, -c)')
    template = infile.read() if infile else string
    try:
        manifest = Manifest.from_template(template, define)
    except TOMLDecodeError as err:
        click.echo(f'ERROR: failed to parse manifest template: {err!s}', err=True)
        ctx.exit(1)

    if check:
        try:
            manifest.check()
        except voluptuous.MultipleInvalid as err:
            click.echo(f'ERROR: manifest failed validation: {err!s}', err=True)
            ctx.exit(1)

    manifest.expand_all_trusted_files(chroot=chroot)
    manifest.dump(outfile)

if __name__ == '__main__':
    main() # pylint: disable=no-value-for-parameter
